package br.edu.ufcg.greengrid.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class InputLazyList<E> extends AbstractLazyList<E> {

	private List<Iter> iterators;
	
	public InputLazyList(File input, Transform<E> transform) {
		super(input, transform);
		this.iterators = new LinkedList<Iter>();
	}

	@Override
	public Iterator<E> iterator() {
		Iter iter = new Iter(this.file, this.transform);
		this.iterators.add(iter);
		return iter;
	}

	private class Iter implements Iterator<E> {

		private BufferedReader br;

		private Transform<E> transform;

		public Iter(File file, Transform<E> transform) {
			try {
				this.br = new BufferedReader(new FileReader(file));
			} catch (FileNotFoundException e) {
				throw new RuntimeException(e);
			}
			this.transform = transform;
		}

		@Override
		public boolean hasNext() {
			boolean ans = false;
			try {
				this.br.mark(1);
				if (this.br.read() != -1) {
					ans = true;
				}
				this.br.reset();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return ans;
		}

		@Override
		public E next() {
			try {
				return this.transform.from(this.br.readLine());
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}

		@Override
		public void remove() {
			throw new UnsupportedOperationException();
		}

		public void close() {
			if (this.br != null) {
			try {
				this.br.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		}
		
	}
	
	public void close() {
		for (Iterator<Iter> iter = this.iterators.iterator(); iter.hasNext();) {
			iter.next().close();
		}
	}

}